package com.flying.srccode;

import com.flying.map.Person;
import org.junit.jupiter.api.Test;

import java.util.LinkedList;

/**
 * @ClassName LinkedListSrc
 * @Author flying
 * @Date 2025/2/1 21:56
 * @Description LinkedList源码分析
 */
public class LinkedListSrc {
    Person first;
    /**
     * 添加节点
     */
    @Test
    void test1(){

        //

        LinkedList<String> list=new LinkedList<>();


        /**
         *
         * 节点类：
         * private static class Node<E> {
         *   E item;
         *   Node<E> next;
         *   Node<E> prev;

         *   Node(Node<E> prev, E element, Node<E> next) {
         *     this.item = element;
         *     this.next = next;
         *     this.prev = prev;
         *    }
         * }
         *
         *
         * 成员变量：
         *   transient int size = 0;   // 链表的节点个数
         *   transient Node<E> first;  // 头结点   null
         *   transient Node<E> last;   // 尾结点   null
         *
         * 添加元素： 地址 1111
         * public boolean add(E e) {
         *   linkLast(e);
         *   return true;
         * }
         *
         * void linkLast(E e) {
         *   final Node<E> l = last;  //  null
         *   final Node<E> newNode = new Node<>(l, e, null);
         *   last = newNode;    // 将成员变量 last尾结点赋值为 newNode
         *   if (l == null)  // l为final 仍为null
         *     first = newNode; // 将 first赋值为 newNode
         *   else
         *     l.next = newNode;
         *   size++;
         *   modCount++;
         * }
         */
        list.add("a");


        // 添加第二个节点: 2222
        /**
         *
         * void linkLast(E e) {
         *   final Node<E> l = last;  //  l --> 地址 "1111"
         *   final Node<E> newNode = new Node<>(l, e, null);
         *   last = newNode;    // 将成员变量 last从上一个节点1111 更新为  newNode  2222
         *   if (l == null)  // 此时的 l 不再是 null --> 1111
         *     first = newNode;
         *   else    // 进入此分支
         *     l.next = newNode;  // 将上一个节点的next属性指向新建节点
         *   size++;
         *   modCount++;
         * }
         */

        /**
         * LinkedList的添加节点流程
         *      将 局部变量 l 赋值为 成员变量last -->  null（首次初始化值为null）;
         *      创建新节点，将新节点的 previous属性为 l,即上一个尾结点;
         *      将成员变量last赋值为新节点引用
         *      通过l是否为null，判断是否是首次添加节点元素，首次则将成员变量first赋值为 新节点引用，
         *      反之，上一个尾结点的next的属性赋值为新节点引用
         *      size和modCount各自曾1
         *
         */

        list.add("a");





    }

    /**
     * 添加头元素
     */
    @Test
    void test2(){
        LinkedList<String> list=new LinkedList<>();

        list.add("a");

        // 添加头元素
        /**
         *     public void addFirst(E e) {
         *         linkFirst(e);
         *     }
         *
         *     private void linkFirst(E e) {
         *      // 注意： f 为 final修饰的常量，引用不可重新修改，但是引用的属性可以修改
         *         final Node<E> f = first;     // 将当前头结点引用赋值给临时变量 f
         *         final Node<E> newNode = new Node<>(null, e, f);  // 创建新节点，将新节点的next属性赋值为 当前的头结点
         *         first = newNode; // 将新创建的节点赋值为头结点
         *         if (f == null)   // 第一次添加节点
         *             last = newNode;  // 尾结点也赋值为 新节点引用
         *         else
         *             f.prev = newNode;  // 将上一个头结点的prev属性赋值为新节点引用
         *         size++;
         *         modCount++;
         *     }
         */
        list.addFirst("b");




    }


    /**
     * 添加尾元素
     */
    @Test
    void test3(){
        LinkedList<String> list=new LinkedList<>();

        list.add("a");


        /**
         *     void linkLast(E e) {
         *         final Node<E> l = last;
         *         final Node<E> newNode = new Node<>(l, e, null);
         *         last = newNode;
         *         if (l == null)
         *             first = newNode;
         *         else
         *             l.next = newNode;
         *         size++;
         *         modCount++;
         *     }
         */
        list.addLast("b");

    }



    @Test
    void test4(){
        Person person = new Person();

        Person p1=new Person("aaaa",12);
        Person p2 = new Person("bbbb", 11);

        System.out.println(first);
        final Person f=p1;
//        f=p2;   f为常量无法重新赋值引用
        f.setName("cccc");
        System.out.println(f);

    }


    /**
     * 获取元素
     */
    @Test
    void test5(){
        LinkedList<String> list=new LinkedList<>();

        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");

        /**
         *     public E get(int index) {
         *         checkElementIndex(index);  //  !(index >= 0 && index < size)
         *         return node(index).item;
         *     }
         *
         *
         *
         *   Node<E> node(int index) {
         *         // assert isElementIndex(index);
         *
         *         if (index < (size >> 1)) {  // 查找元素的位置小于容器个数的一半，则元素里头结点更近，从头结点开始遍历
         *             Node<E> x = first;
         *             for (int i = 0; i < index; i++)
         *                 x = x.next; // 遍历到index的上一个节点时，通过这个节点的next属性直接获取 index节点
         *             return x;
         *         } else {
         *             Node<E> x = last;   // 从尾结点开始遍历
         *             for (int i = size - 1; i > index; i--)
         *                 x = x.prev;
         *             return x;
         *         }
         *     }
         */
        String s = list.get(1);


    }





}
